package com.ljl.mvvmdemo.net

import android.text.TextUtils
import com.ljl.mvvmdemo.net.HttpConstants.BOOK_PROXY_DEPLOY_ENVIRONMENT
import com.ljl.mvvmdemo.net.HttpConstants.BOOK_PROXY_POS_GATEWAY_URL
import com.ljl.mvvmdemo.net.HttpConstants.HW_SIGN_SECRET
import com.ljl.mvvmdemo.util.GlobalDataHelper
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
import okio.Buffer
import org.apache.commons.codec.digest.DigestUtils
import java.io.IOException
import java.math.BigInteger
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.*

/**
 * 拦截器：日志打印、网关验签
 * created by luojialun on 2024/10/23
 */
class LoggingInterceptor : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        //处理请求
        val timeStamp = System.currentTimeMillis().toString()
        val uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase()

        var request = chain.request()
        val requestBuilder = request.newBuilder()
        requestBuilder.addHeader("BooK-Code", GlobalDataHelper.getInstance().getLogin().system_book_code)
            .addHeader("x-book-code", GlobalDataHelper.getInstance().getLogin().system_book_code)
            .addHeader("card_url", "true")
            .addHeader("Content-Type", "application/json")
            .addHeader("Accept", "application/json")
            .addHeader("x-timestamp", timeStamp)
            .addHeader("x-nonce", uuid)

        // TODO: 2024/11/20 token 刷新
        val token = GlobalDataHelper.getInstance().getPosMachine().pos_machine_token
        if (!(request.url.toString().contains("nhsoft.amazon.pos.posmachine.registerv3")
                    || request.url.toString().contains("nhsoft.amazon.system.login")
                    || request.url.toString().contains("nhsoft.amazon.pos.posmachine.refreshtoken")
                    || request.url.toString().contains("nhsoft.amazon.pos.branch.checkLicenseCount")
                    || request.url.toString().contains("nhsoft.amazon.pos.posmachine.fetchtoken"))) {
            if (!TextUtils.isEmpty(token)) {
                //存在token时才加token
                requestBuilder.addHeader("Pos-token", token)
            }
        }
        addHeadSignature(request, requestBuilder, token, timeStamp, uuid)
        request = requestBuilder.build()

        // TODO: 2024/10/23 处理响应
        val response = chain.proceed(request)

        return response.newBuilder().build()
    }

    /**
     * head中添加signature
     *
     * @param requestBuilder
     * @param token
     * @param timeStamp
     * @param uuid
     */
    private fun addHeadSignature(request: Request, requestBuilder: Request.Builder, token: String, timeStamp: String, uuid: String) {
        val url = request.url.toString()
        if (!TextUtils.isEmpty(BOOK_PROXY_POS_GATEWAY_URL) && url.contains(BOOK_PROXY_POS_GATEWAY_URL)) {
            requestBuilder.addHeader("x-environment", BOOK_PROXY_DEPLOY_ENVIRONMENT)
            //走华为网关的接口x-signature生成逻辑调整
            val urlParams: String = getUrlParam(url)
            //Log.e("TAG", "urlParams:" + urlParams);
            var bodyParam = ""
            if ("POST" == request.method) {
                val originalRequestBody = request.body
                if (originalRequestBody?.contentType() != null) {
                    // 检查RequestBody的Content-Type是否为json
                    if ("application/json; charset=utf-8".equals(originalRequestBody.contentType().toString(), ignoreCase = true)) {
                        // 读取json字符串
                        val buffer = Buffer()
                        try {
                            originalRequestBody.writeTo(buffer)
                        } catch (e: IOException) {
                            e.printStackTrace()
                        }
                        bodyParam = buffer.readUtf8()
                        buffer.close()
                    }
                }
            }
            requestBuilder.addHeader("pos-signature", getHWSign(token, timeStamp, uuid, urlParams, bodyParam))
        } else {
            // TODO: 2024/11/20 groupId
            requestBuilder.addHeader("x-signature", getSign(timeStamp, uuid, "").toUpperCase())
        }
    }

    private fun getUrlParam(str: String): String {
        val protocolEnd = str.indexOf("://")
        if (protocolEnd == -1) {
            return str // 如果没有协议头，直接返回
        }
        val url = str.substring(protocolEnd + 3)
        val pathStart = url.indexOf('/')
        return if (pathStart == -1) {
            str // 如果没有找到 '/'，URL格式可能不正确
        } else url.substring(pathStart)
    }

    /**
     * AMA sign
     *
     * @param timeStamp
     * @param nonce
     * @param groupId
     * @return
     */
    private fun getSign(timeStamp: String, nonce: String, groupId: String): String {
        return newMd5(GlobalDataHelper.getInstance().getLogin().system_book_code + timeStamp + nonce + groupId)
    }

    /**
     * 华为 sign
     *
     * @param token
     * @param timeStamp
     * @param nonce
     * @param urlParams
     * @param bodyParams
     * @return
     */
    private fun getHWSign(token: String, timeStamp: String, nonce: String, urlParams: String, bodyParams: String): String {
        val md5Content = token + timeStamp + nonce + HW_SIGN_SECRET + urlParams + bodyParams + HW_SIGN_SECRET
        return DigestUtils.md5Hex(md5Content)
    }

}

/**
 * md5加密
 *
 * @param plainText
 * @return
 */
fun newMd5(plainText: String): String {
    //定义一个字节数组
    var secretBytes: ByteArray? = null
    secretBytes = try {
        // 生成一个MD5加密计算摘要
        val md = MessageDigest.getInstance("MD5")
        //对字符串进行加密
        md.update(plainText.toByteArray())
        //获得加密后的数据
        md.digest()
    } catch (e: NoSuchAlgorithmException) {
        throw RuntimeException("没有md5这个算法！")
    }
    //将加密后的数据转换为16进制数字
    var md5code = BigInteger(1, secretBytes).toString(16) // 16进制数字
    // 如果生成数字未满32位，需要前面补0
    val length = md5code.length
    if (length < 32) {
        for (i in 0 until 32 - length) {
            md5code = "0$md5code"
        }
    }
    return md5code
}